/*
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package botobjects;

import interfaces.BotObject;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import tools.StringTools;

/**
 * Represents an army in a SoM
 * 
 * 
 */
public class SoMArmy implements BotObject {
   private String race = "";
   private Long returnTime = 0L;
   private int soldiers = 0;
   private int dspecs = 0;
   private int ospecs = 0;
   private int elites = 0;
   private int thieves = 0;
   private int armyno = 0;
   private int land = 0;
   private int armyType = 0;
   private int generals = 1;

   public SoMArmy(final SoMArmy army) {
	  race = army.getRace();
	  returnTime = army.getReturnTime();
	  soldiers = army.getSoldiers();
	  dspecs = army.getDspecs();
	  ospecs = army.getOspecs();
	  elites = army.getElites();
	  armyno = army.getArmyno();
	  armyType = army.getArmyType();
	  thieves = army.getThieves();
	  land = army.getLand();
	  generals = army.getGenerals();
   }

   public SoMArmy(final String race, final int soldiers, final int dspecs, final int ospecs, final int elites,
		 final int armyType, final int land) {
	  this.race = race;
	  this.soldiers = soldiers;
	  this.dspecs = dspecs;
	  this.ospecs = ospecs;
	  this.elites = elites;
	  this.armyType = armyType;
	  this.land = land;
   }

   public SoMArmy(final String race, final int soldiers, final int dspecs, final int ospecs, final int elites, final int thieves,
		 final int armyType, final int land) {
	  this.race = race;
	  this.soldiers = soldiers;
	  this.dspecs = dspecs;
	  this.ospecs = ospecs;
	  this.elites = elites;
	  this.thieves = thieves;
	  this.armyType = armyType;
	  this.land = land;
   }

   public SoMArmy(final String race, final Long returnTime, final int armyno, final int armyType) {
	  this.race = race;
	  this.returnTime = returnTime;
	  this.armyno = armyno;
	  this.armyType = armyType;
   }

   public SoMArmy(final String race, final Long returnTime, final int soldiers, final int ospecs, final int elites,
		 final int armyno, final int armyType, final int land, final int generals) {
	  this.race = race;
	  this.returnTime = returnTime;
	  this.soldiers = soldiers;
	  this.ospecs = ospecs;
	  this.elites = elites;
	  this.armyno = armyno;
	  this.armyType = armyType;
	  this.land = land;
	  this.generals = generals;
   }

   /**
    * Calculates how much offense is needed to ambush this army
    * 
    * @return the amount of offense needed to ambush this army. Returns 0 if race can't be found
    */
   public int getAmbushOff() {
	  Race raceInfo = Race.getRace(race);
	  if (raceInfo == null)
		 return 0;
	  Double offReq = (getSoldiers() * 1 + getOspecs() * raceInfo.getDspecstr() + getElites() * raceInfo.getElitedstr()) * 0.8;
	  return (int) Math.ceil(offReq);
   }

   public int getArmyno() {
	  return armyno;
   }

   public int getArmyType() {
	  return armyType;
   }

   public int getDspecs() {
	  return dspecs;
   }

   public int getElites() {
	  return elites;
   }

   @Override
   public List<String> getIRCOutput(final int outputType, final String... args) {
	  return new LinkedList<String>();
   }

   public int getOspecs() {
	  return ospecs;
   }

   public String getRace() {
	  return race;
   }

   public Long getReturnTime() {
	  return returnTime;
   }

   @Override
   public Map<String, Object> getRPCOutput(final int... includes) {
	  Map<String, Object> out = new HashMap<String, Object>();
	  if (StringTools.isNullOrEmpty(getRace()) || getReturnTime() == null)
		 return out;
	  if (getReturnTime() > 0L) {
		 out.put("Return Time", new Date(getReturnTime()));
	  }
	  if (getSoldiers() > 0) {
		 out.put("Soldiers", getSoldiers());
	  }
	  if (getDspecs() > 0) {
		 out.put("Def Specs", getDspecs());
	  }
	  if (getOspecs() > 0) {
		 out.put("Off Specs", getOspecs());
	  }
	  if (getElites() > 0) {
		 out.put("Elites", getElites());
	  }
	  if (getThieves() > 0) {
		 out.put("Thieves", getThieves());
	  }
	  if (getArmyno() > 0) {
		 out.put("Army Number", getArmyno());
	  }
	  return out;
   }

   public int getSoldiers() {
	  return soldiers;
   }

   public int getThieves() {
	  return thieves;
   }

   @Override
   public boolean saveToDB() {
	  return false;
   }

   public void setDspecs(final int dspecs) {
	  this.dspecs = dspecs;
   }

   public void setElites(final int elites) {
	  this.elites = elites;
   }

   public void setOspecs(final int ospecs) {
	  this.ospecs = ospecs;
   }

   public void setSoldiers(final int soldiers) {
	  this.soldiers = soldiers;
   }

   public void setThieves(final int thieves) {
	  this.thieves = thieves;
   }

   public int getLand() {
	  return land;
   }

   public void setLand(int land) {
	  this.land = land;
   }

   public int getGenerals() {
	  return generals;
   }

   public void setGenerals(int generals) {
	  this.generals = generals;
   }
}
